namespace SPDeploy
{
    using System;
    using System.Collections.Generic;
    using Library.Helpers;
    using Library.Interfaces;
    using Library.Logging;

    internal class ConsoleLogWriter : ILogWriter
    {
        public ConsoleLogWriter()
        {
            MinimumSeverity = LogSeverity.SubStep;
        }

        #region Properties: public

        public LogSeverity MinimumSeverity { get; set; }

        #endregion

        #region ILogWriter Members

        public void Write(LogSeverity severity, string sourceName, string format, params object[] args)
        {
            if ((int) severity < (int) MinimumSeverity)
            {
                return;
            }

            int currentLine = Console.CursorTop;

            ConsoleColor fgColor = Console.ForegroundColor;

            if (severity != LogSeverity.SubStep)
            {
                Console.ForegroundColor = GetColorForSeverity(severity);
                Console.Write(severity);

                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.CursorLeft = 10;
                Console.Write(sourceName);
            }

            int endRow = WrappedWrite(ConsoleColor.White, string.Format(format, args), Console.CursorTop, 35, Console.WindowWidth);

            Console.ForegroundColor = fgColor;
        }

        private static int WrappedWrite(ConsoleColor color, string text, int startRow, int startColumn, int lastColumn)
        {
            if (startColumn > lastColumn)
            {
                throw new ArgumentException("lastColumn can't be less than startColumn");
            }

            ConsoleColor prevColor = Console.ForegroundColor;
            Console.ForegroundColor = color;
            Console.CursorTop = startRow;
            int maxLineLength = (lastColumn - startColumn) - 1;
            List<string> lines = new LineSplitter(maxLineLength, text).Lines;
            foreach (string s in lines)
            {
                Console.CursorLeft = startColumn;
                Console.Out.WriteLine(s);
            }
            Console.ForegroundColor = prevColor;
            return startRow + lines.Count;
        }

        #endregion

        #region Methods: private

        private static ConsoleColor GetColorForSeverity(LogSeverity severity)
        {
            switch (severity)
            {
                case LogSeverity.Step:
                    return ConsoleColor.Green;
                case LogSeverity.SubStep:
                    return ConsoleColor.DarkGreen;
                case LogSeverity.Error:
                    return ConsoleColor.Red;
                case LogSeverity.Warning:
                    return ConsoleColor.Yellow;
                case LogSeverity.Info:
                    return ConsoleColor.Gray;
                case LogSeverity.Verbose:
                    return ConsoleColor.DarkGray;
                default:
                    return ConsoleColor.Gray;
            }
        }

        #endregion
    }
}